package com.hb.B_面向对象.K_多态和拓展

import com.hb.C_Lambda表达式和集合.test

fun main() {
    /**
     * 1. run方法
    public inline fun <T, R> T.run(block: T.() -> R): R
     *
     * 简单来说，run是任何类型T的通用函数，run中执行了返回类型为R的扩展函数block,
     * 最终返回该扩展函数的结果。
     * 在run函数中，我们拥有一个单独的作用域，能够重新定义一个nickName变量，并且它的
     * 作用域只存在于run函数中。
     *
     * 这个范围函数本身似乎不是很有用，但是相比范围，还有一点不错的是，他返回范围内最后一个对象
     *
     * 场景：用户点击领取新人的奖励的按钮，如果用户此时还没有登录则弹出loginDialog,如果已经登录
     * 则弹出领取奖励的getNewAccountDialog.我们可以使用以下代码来处理这个逻辑：
      run{
        if(!isLogin) loginDialog else getNewAccountDialog
      }
     */
    val listOf = listOf(1, 2, 3)
   val result= listOf.run(List<Int>::test)
    println("result=$result")

    val result2=listOf.run {
        return@run "hello"
    }
    println("result2=$result2")

    //作用域问题
    val nickName="nickName"
    run {
        val nickName="run nickName"
        println("in run =$nickName")
    }
    println(nickName)

    //let
    /**
        public inline fun <T, R> T.let(block: (T) -> R): R
     *  let和apply类似，唯一不同的是返回值，apply返回的是原来的对象，而let
     *  返回的是闭包里面最后一行的值。

     */
    val result3=listOf.let {
        it[0]
    }
    println("result3=$result3")

    //3. also =let +apply
    /**
     * public inline fun <T> T.also(block: (T) -> Unit): T
     * also函数的参数是一个block函数，block函数的参数是一个调用also方法的对象
     * 在方法块内使用it来代替。block函数没有返回值。also函数的返回值还是他本身的对象
     */
    val result4=listOf.also {
        it[1]
    }
    println("result4=$result4")

    //takeIf
    /**
     * 如果我们不仅仅只想判空，还想加入条件，这时let可能显得有点不足。
     * public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T?
     *
     * 如果接收者的数据传入到predicate 函数中去有返回false的，就返回接收者为null
     */
    val result5=listOf.takeIf {
        it[1]>10
    }
    println("result5=$result5")
}

fun List<Int>.test():String{
    return "hello"
}